/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import socket from '@ohos.net.socket';
import wifi from '@ohos.wifiManager';
import util from '@ohos.util';
import { Level } from '../Level';
import { Appender } from '../config/Appender'

var tcp = socket.constructTCPSocketInstance();

export class SMTPAppender {
    private fromMail: string
    private toMail: string
    private subject: string
    private smtpHost: string
    private smtpPort: number
    private username: string
    private password: string
    private OUT_TIME = 6000
    private mailMsg = ''

    bind(appender: Appender) {
        this.fromMail = appender.fromMail
        this.toMail = appender.toMail
        this.subject = appender.subject
        this.smtpHost = appender.smtpHost
        this.smtpPort = appender.smtpPort
        this.username = new util.Base64Helper().encodeToStringSync(new util.TextEncoder().encodeInto(appender.username))
        this.password = new util.Base64Helper().encodeToStringSync(new util.TextEncoder().encodeInto(appender.password))

        let ipInfo = wifi.getIpInfo()
        let ip = this.intToIP(ipInfo.ipAddress)
        let promise = tcp.bind({ address: ip, port: 0, family: 1 });
        promise.then(() => {
            tcp.connect({
                address: { address: this.smtpHost, port: this.smtpPort },
                timeout: this.OUT_TIME
            }, err => {
                if (err) {
                    tcp.close()
                    return;
                }
            })
        }).catch(err => {
            tcp.close()
            console.error('bind tcp fail ' + JSON.stringify(err));
        });
    }

    async start(effectiveLevelInt: number, level: Level, msg: string) {
        if (effectiveLevelInt > level.getLevelInt())return;
        this.mailMsg += (level.getLevelStr() + ' ' + msg + '\n')
        await tcp.send({
            data: "AUTH LOGIN\r\n" + //发送登陆命令
            this.username + "\r\n" + //发送用户名的base64编码
            this.password + "\r\n" + //发送密码的base64编码
            "MAIL FROM: <" + this.fromMail + ">\r\n" + //发送用户名
            "RCPT TO: <" + this.toMail + ">\r\n", //发送收件人地址
            encoding: "UTF-8"
        }).catch(err => {
            tcp.close()
            console.info('error -> ' + JSON.stringify(err));
        })
        await tcp.send({
            data: "DATA\r\n", //发送数据命令
            encoding: "UTF-8"
        }).catch(err => {
            tcp.close()
            console.info('error -> ' + JSON.stringify(err));
        })
        await tcp.send({
            data: "From:" + this.fromMail + "\r\n" //发件人，要和前面的一致
            + "To:" + this.toMail + "\r\n" //收件人，要和前面的一致
            + "Subject:" + this.subject + "\r\n\r\n",
            encoding: "UTF-8"
        }).catch(err => {
            tcp.close()
            console.info('error -> ' + JSON.stringify(err));
        })
        await tcp.send({
            data: "\r\t" + this.mailMsg, //邮件正文内容
            encoding: "UTF-8"
        }).catch(err => {
            tcp.close()
            console.info('error -> ' + JSON.stringify(err));
        })
        await tcp.send({
            data: "\r\n.\r\n", //结束标志
            encoding: "UTF-8"
        }).catch(err => {
            tcp.close()
            console.info('error -> ' + JSON.stringify(err));
        })
        tcp.close()
    }

    intToIP(num) {
        var str;
        var tt = new Array();
        tt[0] = (num >>> 24) >>> 0;
        tt[1] = ((num << 8) >>> 24) >>> 0;
        tt[2] = (num << 16) >>> 24;
        tt[3] = (num << 24) >>> 24;
        str = String(tt[0]) + "." + String(tt[1]) + "." + String(tt[2]) + "." + String(tt[3]);
        return str;
    }
}